package me.fenglu.autodeploy;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;

public class GitHelper {
	
	public static List<Map<String, Object>> changedFiles(String gitProjPath, String prevCommitId){
		
		List<Map<String, Object>> changedFiles = new ArrayList<Map<String, Object>>();
		
		File dir = new File(gitProjPath);
		Git git = null;
		Repository repo = null;
		RevWalk rw = null;
		DiffFormatter df = null;
		try {
			git = Git.open(dir);
			repo = git.getRepository();
			rw = new RevWalk(repo);
			String branch = repo.getBranch();
			if(branch.equals("master")) {
				
				RevCommit lastDeployedCommit = rw.parseCommit(ObjectId.fromString(prevCommitId));
				RevTree lastDeployedTree = lastDeployedCommit.getTree();
				
				RevCommit head = rw.parseCommit(repo.resolve(Constants.HEAD));
				RevTree headTree = head.getTree();
				
				df = new DiffFormatter(new ByteArrayOutputStream());
				df.setRepository(repo);
				List<DiffEntry> changed = df.scan(lastDeployedTree, headTree);
				StringBuilder sb = new StringBuilder();
				Map<String, Object> fileEntry = null;
				for (DiffEntry entry : changed) {
					fileEntry = new HashMap<String, Object>();
					sb.delete(0, sb.length());
					String filePath = "";
					switch (entry.getChangeType()) {
						case ADD:
							fileEntry.put("changeType", "add");
							filePath = entry.getNewPath();
							sb.append("A ").append(filePath);
							break;
						case DELETE:
							fileEntry.put("changeType", "delete");
							filePath = entry.getOldPath();
							sb.append("D ").append(filePath);
							break;
						case MODIFY:
							fileEntry.put("changeType", "modify");
							filePath = entry.getNewPath();
							sb.append("M ").append(entry.getNewPath());
							break;
						case COPY:
							sb.append("[Copied] from ").append(entry.getOldPath()).append(" to ").append(entry.getNewPath());
							break;
						case RENAME:
							sb.append("[Renamed] from ").append(entry.getOldPath()).append(" to ").append(entry.getNewPath());
							break;
					}
					
					if(!filePath.equals("")) {
						fileEntry.put("filePath", filePath);
						String fileType = filePath.substring(filePath.lastIndexOf(".")+1, filePath.length());
						fileEntry.put("fileType", fileType);
					}
					if (sb.toString().length() > 0) {
						changedFiles.add(fileEntry);
						System.err.println(sb.toString());
					}
				}
			}else {
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(null != rw) {
				rw.close();
			}
			if(null != df) {
				df.close();
			}
		}
		return changedFiles;
	}
	
}
